We would like to connect specific user groups with specific extranet areas ('Project rooms'). In order to list Project rooms easily, we would like to add a field to the Role template so that we can add the path to the Project room with which it is associated. How can we add a custom field to a role?
Sitecore does not provide the Role Manager, only the User Manager. However, you can create your own Role Manager XAML application which works with your custom Role fields. Please follow these steps as an example for Sitecore 5.2:
<template id="{A7DF04B4-4C4B-44B7-BE1E-AD901BD53DAD}" name="Role" fullname="Role" icon="Network/16x16/id_card.png" baseids="">
<section id="" name="Appearance" icon="">
<field id="{06D5295C-ED2F-4A54-9BF2-26228D113318}" name="Icon" icon="" shared="1" sortorder="" source="" style="" type="text" unversioned="1">Network/16x16/id_card.png</field>
</section>
<section id="" name="Data" icon="">
<field id="{4C5B18DC-7794-47C6-9C27-A2ACC39885B1}" name="Fullname" icon="" shared="1" sortorder="" source="" style="" type="text" unversioned="1"/>
</section>
</template>
<CodeBeside Type="Custom.CustomSecurityManagerForm,CustomSecurityManagerForm"/>
using System;
using System.Collections.Generic;
using System.Text;
using Sitecore;
using Sitecore.Web.UI.Sheer;
using Sitecore.Text;
using Sitecore.Shell.Applications.Security.SecurityManager;
using Sitecore.Data;
using Sitecore.Web.UI.WebControls;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Data.Items;
using Sitecore.SecurityModel;
using Sitecore.Configuration;
namespace Custom
{
public class CustomSecurityManagerForm : SecurityManagerForm
{
new protected void Open()
{
base.Open();
Item itm = this.GetSelectedItem();
if ((itm != null) && (itm.TemplateID == TemplateIDs.Role))
{
Domain domain = Factory.GetDomain(this.Domain);
if (domain != null)
{
EditRole(Factory.GetDomain(this.Domain), itm.ID);
}
}
}
public void EditRole(Domain domain, ID id)
{
UrlString url = new UrlString("/sitecore/shell/default.html?xmlcontrol=SecurityEditRole");
url.Add("do", domain.Name);
url.Add("id", id.ToString());
Context.ClientPage.ClientResponse.ShowModalDialog(url.ToString(), "local:refresh");
}
public override void HandleMessage(Message message)
{
if (message.Name == "local:refresh")
{
Sitecore.Context.ClientPage.ClientResponse.SetLocation(string.Empty);
}
base.HandleMessage(message);
}
private Item GetSelectedItem()
{
foreach (ListviewItem itm in this.Listview.Items)
{
if (Context.ClientPage.ClientRequest.Source == itm.ID)
{
return this.DataContext.GetItem((itm as DataListviewItem).ItemID);
}
}
return null;
}
}
}
4. We are going to create the Role Manager. Please copy \sitecore\shell\Applications\Security\Edit user\Edit user.xml to \sitecore\shell\Override\edit role.xml
5. Here is the body of this XAML:
<?xml version="1.0" encoding="utf-8" ?>
<control xmlns="http://schemas.sitecore.net/Visual-Studio-Intellisense" >
<SecurityEditRole>
<FormDialog Icon="People/32x32/user1_view.png" Header="Edit user"
Text="Change the role information. When done, click the Save button" OKButton="Save">
<CodeBeside Type="Custom.EditRoleForm,CustomSecurityManagerForm"/>
<GridPanel ID="Fields" Columns="2" Width="100%" CellPadding="2">
<Literal Text="Role name:" GridPanel.NoWrap="true"/>
<Edit ID="Name" Width="100%" ReadOnly="true" background="#e9e9e9" Border="none" GridPanel.Width="100%"/>
<Literal Text="Full name:" GridPanel.NoWrap="true" GridPanel.VAlign="top"/>
<Edit ID="FullName" Width="100%" GridPanel.Width="100%"/>
</GridPanel>
</FormDialog>
</SecurityEditRole>
</control>
Please pay attention to the CodeBeside.
6. Here is the codebeside class:
using System;
using System.Collections.Generic;
using System.Text;
using Sitecore;
using Sitecore.Text;
using Sitecore.Shell.Applications.Security.SecurityManager;
using Sitecore.Data;
using Sitecore.Diagnostics;
using Sitecore.Configuration;
using Sitecore.SecurityModel;
using Sitecore.Web.UI.WebControls;
using Sitecore.Web;
using Sitecore.Web.UI.Pages;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Data.Items;
using Sitecore.Data.Fields;
namespace Custom
{
class EditRoleForm : DialogForm
{
protected Edit Name;
protected Edit FullName;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!Context.ClientPage.IsEvent)
{
string domainString = WebUtil.GetQueryString("do");
if (domainString.Length == 0)
{
domainString = Context.GetDomainName();
}
this.Domain = domainString;
string idRole = WebUtil.GetQueryString("id");
Error.Assert(idRole.Length > 0, "Querystring parameter \"id\" not found.");
Domain domain = Sitecore.Configuration.Factory.GetDomain(this.Domain);
Sitecore.SecurityModel.RoleItem roleItem = domain.GetRole(idRole);
Error.Assert(roleItem != null, "Role \"" + idRole + "\" not found");
this.Name.Value = roleItem.Name;
roleItem.InnerItem.Fields.ReadAll();
roleItem.InnerItem.Fields.Sort();
foreach (Field field in roleItem.InnerItem.Fields)
{
if (field.Key.Length > 0)
{
//Restore value to Full name filed
if (field.Name.Equals("Fullname"))
{
FullName.Value = field.Value;
}
}
}
Context.ClientPage.ServerProperties["id"] = idRole;
}
}
public string Domain
{
get
{
return StringUtil.GetString(Context.ClientPage.ServerProperties["Domain"]);
}
set
{
Context.ClientPage.ServerProperties["Domain"] = value;
}
}
protected override void OnOK(object sender, EventArgs args)
{
string idRole = Context.ClientPage.ServerProperties["id"] as string;
Domain domain = Sitecore.Configuration.Factory.GetDomain(this.Domain);
Sitecore.SecurityModel.RoleItem roleItem = domain.GetRole(idRole);
if (roleItem != null)
{
roleItem.InnerItem.Fields.ReadAll();
roleItem.InnerItem.Editing.BeginEdit();
roleItem["FullName"] = StringUtil.GetString(Context.ClientPage.ClientRequest.Form["FullName"]);
roleItem.InnerItem.Editing.EndEdit();
Sitecore.Context.ClientPage.ClientResponse.SetDialogValue("Ok");
base.OnOK(sender, args);
}
else
{
Context.ClientPage.ClientResponse.ShowError("Failed to save role.", "");
}
}
}
}
See more relevant methods: OnLoad() in which you should output your custom fields and OnOK in which you should save data in the custom fileds (see the image below).
Download the sources for this article by following the links below: